package com.sunday.common.core.remoting.base.response;

import com.sunday.common.core.constants.LogConstants;
import com.sunday.common.core.constants.StringConstants;
import com.sunday.common.core.enums.ErrorCodeEnum;
import com.sunday.common.core.enums.InnerErrorCodeEnum;
import com.sunday.common.core.exception.CoreException;
import com.sunday.common.core.remoting.base.response.core.ExceptionResolve;
import com.sunday.common.core.remoting.base.response.core.ThrowableFilter;
import lombok.extern.slf4j.Slf4j;

/**
 * 异常处理响应
 *
 * @author zsy
 * @since 2022/10/14
 */
@Slf4j
public class ExceptionResponse {

    /**
     * 项目内部异常处理
     * 未知异常            -> 统一进行 B0_001 系统执行出错 返回
     * CoreException 异常 -> 打印真实错误信息，并且复用 CoreException 异常信息进行 Response内容的拼装
     */
    public static final ExceptionResolve<Response> RESPONSE_RESOLVE =
            ((filter, error) -> {
                // B0_001(ErrorClassifyEnum.B + "0001","系统执行出错")
                Response response = Response.error(ErrorCodeEnum.B0_001);
                if (error instanceof CoreException exception) {
                    response = Response.resultReturn(exception.getCode(), exception.getMessage());
                    log.info(LogConstants.response_format_nack, response, StringConstants.EMPTY);
                    return response;
                }
                log.error(LogConstants.response_format_nack, response, error.toString(), error);
                return response;
            });

    /**
     * RPC交互异常
     * 未捕获异常  -> 统一进行 C0_110 RPC 服务出错 返回
     * 匹配异常    -> 打印真实错误信息，并采用 C0_001 调用第三方服务出错 进行反馈， C0_001 定义为结果未知
     */
    public static final ExceptionResolve<Response> RPC_RESPONSE_RESOLVE =
            ((filter, error) -> {
                // C0_110(ErrorClassifyEnum.C + "0110","RPC 服务出错")
                Response response = Response.error(ErrorCodeEnum.C0_110);
                if (filter.matches(error)) {
                    // C0_001(ErrorClassifyEnum.C + "0001","调用第三方服务出错"),
                    response = Response.resultReturn(InnerErrorCodeEnum.C0_001.errorCode, InnerErrorCodeEnum.C0_001.errorMessage);
                    log.error(LogConstants.error_response_format, response, error.toString(), error);
                    return response;
                }
                log.error(LogConstants.error_response_format, response, error.toString(), error);
                return response;
            });

    /**
     * HTTP交互异常
     * 未捕获异常  -> 统一进行 C0_150 网络资源服务出错 返回
     * 匹配异常    -> 打印真实错误信息，并采用 C0_001 调用第三方服务出错 进行反馈， C0_001 定义为结果未知
     */
    public static final ExceptionResolve<Response> HTTP_RESPONSE_RESOLVE =
            ((filter, error) -> {
                // C0_150(ErrorClassifyEnum.C + "0150","网络资源服务出错")
                Response response = Response.error(ErrorCodeEnum.C0_150);
                if (filter.matches(error)) {
                    // C0_001(ErrorClassifyEnum.C + "0001","调用第三方服务出错"),
                    response = Response.resultReturn(InnerErrorCodeEnum.C0_001.errorCode, InnerErrorCodeEnum.C0_001.errorMessage);
                    log.error(LogConstants.error_response_format, response, error.toString(), error);
                    return response;
                }
                log.error(LogConstants.error_response_format, response, error.toString(), error);
                return response;
            });

    /**
     * 项目内部异常缺省方案 RESPONSE_RESOLVE
     *
     * @param cause
     * @return {@link Response<T>}
     */
    public static <T> Response<T> returnResponse(Throwable cause) {
        return RESPONSE_RESOLVE.resolve(ThrowableFilter.DEFAULT_FILTER, cause);
    }

}
